package com.ruoyi.controller;

import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.dto.ActivitiDto;
import com.ruoyi.util.ActivitiUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

@Api(tags = "工作流管理")
@RestController
@RequestMapping("/activiti")
public class ActivitiController {

    @ApiOperation(value = "部署流程文件")
    @PostMapping("/deploy")
    public AjaxResult deploy(@RequestBody ActivitiDto.DeployDto deployDto) {
        try {
            // 调用工具类方法进行部署
            Deployment deployment = ActivitiUtil.deployProcessDefinitionByAbsolutePath(deployDto.getBpmnAbsoluteFilePath(), deployDto.getDeploymentName());

            // 获取 RepositoryService
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
            RepositoryService repositoryService = processEngine.getRepositoryService();

            // 根据部署 ID 获取流程定义
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                    .deploymentId(deployment.getId())
                    .singleResult();

            // 获取流程定义 ID
            String processDefinitionId = processDefinition.getId();

            // 返回包含流程定义 ID 的成功响应
            return AjaxResult.success().put("processDefinitionId", processDefinitionId);
        } catch (Exception e) {
            return AjaxResult.error("流程文件部署失败：" + e.getMessage());
        }
    }

    @ApiOperation(value = "通过流程定义ID流程实例并关联业务ID")
    @PostMapping("/startProcessInstance")
    public AjaxResult startProcessInstance(@RequestBody ActivitiDto.StartProcessInstance startProcessInstance) {
        try {
            ProcessInstance processInstance = ActivitiUtil.startProcessInstanceById(
                    startProcessInstance.getProcessDefinitionId(),
                    startProcessInstance.getBusinessId(),
                    startProcessInstance.getVariables()
            );
            // 返回流程实例ID
            return AjaxResult.success().put("processInstanceId", processInstance.getId());
        } catch (Exception e) {
            return AjaxResult.error("启动流程实例失败：" + e.getMessage());
        }
    }

    @ApiOperation(value = "根据流程实例ID获取流程变量")
    @GetMapping("/getProcessVariables")
    public AjaxResult getProcessVariables(@ApiParam("流程实例ID") @RequestParam String processInstanceId) {
        try {
            Map<String, Object> variables = ActivitiUtil.getProcessVariablesByProcessInstanceId(processInstanceId);
            if (variables != null) {
                return AjaxResult.success(variables);
            } else {
                return AjaxResult.error("未找到对应的流程实例或流程变量");
            }
        } catch (Exception e) {
            return AjaxResult.error("获取流程变量失败：" + e.getMessage());
        }
    }

    @ApiOperation(value = "根据流程定义Key获取所有流程定义ID")
    @GetMapping("/getProcessDefinitionIdsByKey")
    public AjaxResult getProcessDefinitionIdsByKey(@ApiParam("流程定义Key") @RequestParam String processDefinitionKey) {
        try {
            return AjaxResult.success(ActivitiUtil.getProcessDefinitionIdsByKey(processDefinitionKey));
        } catch (Exception e) {
            return AjaxResult.error("获取流程定义ID失败：" + e.getMessage());
        }
    }

    @ApiOperation(value = "根据流程定义ID获取所有流程实例")
    @GetMapping("/getProcessInstancesByDefinitionId")
    public AjaxResult getProcessInstancesByDefinitionId(@ApiParam("流程定义ID") @RequestParam String processDefinitionId) {
        try {
            return AjaxResult.success(ActivitiUtil.getProcessInstancesByDefinitionId(processDefinitionId));
        } catch (Exception e) {
            return AjaxResult.error("获取流程实例失败：" + e.getMessage());
        }
    }

    @ApiOperation(value = "根据流程实例ID查询任务列表")
    @GetMapping("/getTasksByProcessInstanceId")
    public AjaxResult getPendingTasksByProcessInstanceId(@ApiParam("流程实例ID") @RequestParam String processInstanceId) {
        try {
            return AjaxResult.success(ActivitiUtil.getTasksByProcessInstanceId(processInstanceId));
        } catch (Exception e) {
            return AjaxResult.error("获取待审批的任务列表失败：" + e.getMessage());
        }
    }

    @ApiOperation(value = "根据任务ID完成审批")
    @PostMapping("/completeTaskById")
    public AjaxResult completeTaskById(@RequestBody ActivitiDto.completeTaskDto completeTaskDto) {
        try {
            ActivitiUtil.completeTaskById(completeTaskDto.getTaskId(), completeTaskDto.getIsPass(), null);
            return AjaxResult.success();
        } catch (Exception e) {
            return AjaxResult.error("完成任务失败：" + e.getMessage());
        }
    }

    @ApiOperation(value = "根据流程实例ID获取流程图")
    @GetMapping("/getDiagramByProcessInstanceId")
    public AjaxResult getDiagramByProcessInstanceId(@ApiParam("流程实例ID") @RequestParam String processInstanceId) {
        try {
            return AjaxResult.success().put("base64", ActivitiUtil.getDiagramByProcessInstanceId(processInstanceId));
        } catch (Exception e) {
            return AjaxResult.error("获取流程图失败：" + e.getMessage());
        }
    }
}
